package org.andu.java_gobang.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.andu.java_gobang.game.MatchRequest;
import org.andu.java_gobang.game.MatchResponse;
import org.andu.java_gobang.game.Matcher;
import org.andu.java_gobang.game.OnlineUserManager;
import org.andu.java_gobang.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

//通过这个类来处理匹配功能中的 websocket 请求
@Component
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //玩家上线,加入到OnlineUserManager中

        //1.先获取到当前用户的信息
        try {
            //在注册WebSocket时加上的 .addInterceptors
            //把HttpSession中的Attribute都给拿到WebSocket中了
            //此时就可以在WebSocket中把之前HttpSession里存的user对象拿到了
            //如果用户直接通过域名访问大厅,那么user就会为空
            User user = (User) session.getAttributes().get("user");

            //2.判定当前用户是否已经登录过(在线),
            if (onlineUserManager.getFromGameHall(user.getUserId()) != null
                    || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                //需要告知用户重复登录了
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setReason("当前禁止多开游戏");
                response.setMessage("repeatConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
//                session.close();
                return;
            }

            //3. 拿到了身份信息之后,将玩家设置为在线状态
            onlineUserManager.enterGameHall(user.getUserId(), session);
            broadcastOnlineStats();
            System.out.println("玩家" + user.getUsername() + "进入游戏大厅");
        } catch (NullPointerException e) {
            System.out.println("[MatchAPI.afterConnectionEstablished] 当前用户未登录");
            //出现空指针异常,说明用户未登录,需要返回这个信息
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("没有进行登录操作,无法进入匹配");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //实现处理开始匹配请求和处理停止匹配请求
        User user = (User) session.getAttributes().get("user");

        //获取到客户端给服务器发送的数据
        String payload = message.getPayload();
        //当前这个数据载荷是一个JSON格式的字符串,需要转Java对象.MatchRequest
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {
            //进入匹配队列
            matcher.add(user);
            //返回响应给客户端
            response.setOk(true);
            response.setMessage("startMatch");
        } else if (request.getMessage().equals("stopMatch")) {
            //退出匹配队列
            matcher.remove(user);
            //返回响应给客户端
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            response.setOk(false);
            response.setReason("非法的(匹配)请求");
        }
        String jsonString = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(jsonString));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            //玩家下线,从OnlineUserManager中删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                //                onlineUserManager.exitGameHall(user.getUserId());
                onlineUserManager.completeExit(user.getUserId());
                broadcastOnlineStats();
            }
            //如果玩家正在匹配,websocket连接断开,那么应该移出匹配队列
            matcher.remove(user);
        } catch (NullPointerException e) {
            System.out.println("[MatchAPI.handleTransportError] 当前用户未登录");
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            //玩家下线,从OnlineUserManager中删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
//                onlineUserManager.exitGameHall(user.getUserId());
                onlineUserManager.completeExit(user.getUserId());
                broadcastOnlineStats(); 
            }
            //如果玩家正在匹配,websocket连接断开,那么应该移出匹配队列
            matcher.remove(user);
        } catch (NullPointerException e) {
            System.out.println("[MatchAPI.afterConnectionClosed] 当前用户未登录");
        }
    }

    private void broadcastOnlineStats() throws IOException {
        int total = onlineUserManager.getOnlineCount();

        MatchResponse response = new MatchResponse();
        response.setOk(true);  // 确保设置ok字段
        response.setMessage("onlineStats");
        response.setTotalOnline(total);

        String json = objectMapper.writeValueAsString(response);

        // 广播给所有大厅用户
        for (WebSocketSession session : onlineUserManager.getAllGameHallSessions()) {
            session.sendMessage(new TextMessage(json));
        }
    }
}
